﻿using RsaRegister.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;

namespace RsaRegister
{
   
    public class RsaServer
    {        
        RSACryptoServiceProvider rsa;
        public string pubKey { get; set; }
        public string priKey { get; set; }
        
        public RsaServer()
        {
            rsa = new RSACryptoServiceProvider();
            GenerateKeys();
        }
        public RsaServer( string priviteKey)
        {
            priKey = priviteKey;
            pubKey = priKey.Substring(0, priKey.IndexOf("<P>")) + "</RSAKeyValue>";
            rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(priKey);
        }
        public void GenerateKeys()
        {
            pubKey = rsa.ToXmlString(false);//公钥
            priKey = rsa.ToXmlString(true);//私钥

        }
        public string GenerateRegisterCode(string userString)
        {
            string rc = "";
            rsa.FromXmlString(priKey);
            //加密对象
            RSAPKCS1SignatureFormatter f = new RSAPKCS1SignatureFormatter(rsa);
            f.SetHashAlgorithm("SHA1");
            byte[] source = ASCIIEncoding.ASCII.GetBytes(userString);
            SHA1Managed sha = new SHA1Managed();
            byte[] result = sha.ComputeHash(source);
            byte[] b = f.CreateSignature(result);
            rc = Convert.ToBase64String(b);
            return rc;
        }
        public bool GenerateLicFile(string filename,RegInfo regInfo)
        {
            string rstr = regInfo.GenerateRegString();
            string rc = GenerateRegisterCode(rstr);
            XmlDocument doc = new XmlDocument();
            XmlNode node = doc.CreateXmlDeclaration("1.0", "utf-8", "");
            doc.AppendChild(node);
            XmlNode root = doc.CreateElement("License");
            doc.AppendChild(root);
            var props = typeof(RegInfo).GetProperties();
            foreach (var p in props)
            {
                node = doc.CreateElement(p.Name);
                node.InnerText = p.GetValue(regInfo, null).ToString();
                root.AppendChild(node);
            }
            node = doc.CreateElement("RegisterCode");
            node.InnerText = GenerateRegisterCode(regInfo);
            root.AppendChild(node);
            doc.Save(filename);
            return true;
        }

        /// <summary>
        /// 根据注册信息获取注册码
        /// </summary>
        /// <param name="fullname"></param>
        /// <param name="regInfo"></param>
        /// <returns></returns>
        public string GenerateRegisterCode(RegInfo regInfo)
        {
            string rstr = regInfo.GenerateRegString();
            return GenerateRegisterCode(rstr);
        }
        #region
        //RSA的解密函数  string
        public string RSADecrypt(string m_strDecryptString)
        {
            byte[] PlainTextBArray;
            byte[] DypherTextBArray;
            string Result;

            PlainTextBArray = Convert.FromBase64String(m_strDecryptString);
            DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);
            Result = (new UnicodeEncoding()).GetString(DypherTextBArray);
            return Result;

        }

        //RSA的解密函数  byte
        public string RSADecrypt(byte[] DecryptString)
        {
            byte[] DypherTextBArray;
            string Result;

            DypherTextBArray = rsa.Decrypt(DecryptString, false);
            Result = (new UnicodeEncoding()).GetString(DypherTextBArray);
            return Result;
        }
        #endregion
        #region RSA签名 
        /// <summary>
        /// 对原始数据进行MD5加密
        /// </summary>
        /// <param name="m_strSource">待加密数据</param>
        /// <returns>返回加密后的数据</returns>
        public string GetHash(string m_strSource)
        {
            HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
            byte[] inArray = algorithm.ComputeHash(bytes);
            return Convert.ToBase64String(inArray);
        }
        /// <summary>
        /// 对MD5加密后的密文进行签名
        /// </summary>
        /// <param name="p_strKeyPrivate">私钥</param>
        /// <param name="m_strHashbyteSignature">MD5加密后的密文</param>
        /// <returns></returns>
        public string SignatureFormatter(string m_strHashbyteSignature)
        {
            byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);

            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(rsa);
            formatter.SetHashAlgorithm("MD5");
            byte[] inArray = formatter.CreateSignature(rgbHash);
            return Convert.ToBase64String(inArray);
        }

        #endregion
    }
}

